Skip to content

feat(chat-headers): propagate the resolved user ID via tracestate - #2

Merged
slipfre merged 1 commit into
custom-730from
feat/user-id-tracestate
Aug 19, 2026
Merged

feat(chat-headers): propagate the resolved user ID via tracestate#2
slipfre merged 1 commit into
custom-730from
feat/user-id-tracestate

Conversation

@NoMoreCola

Copy link
Copy Markdown
Collaborator

What

Providers that receive W3C trace context now also receive the resolved user.id as an extra tracestate member:

traceparent: 00-<trace id>-<llm span id>-01
tracestate:  opencode_user_id=<user id>,<other members>

The member is merged into the tracestate produced by propagation rather than replacing it.

Why gated on trace propagation

The injection sits behind the existing OPENCODE_TRACE_PROPAGATION_PROVIDERS check, right after injectTraceContext. Per W3C, a tracestate without a matching traceparent should be dropped by compliant receivers, so tying the two together avoids emitting a header that a standard OTel propagator would silently ignore. Enabling propagation for a provider enables the user ID for it too — no separate opt-in.

Configuration

Setting Env var Default
userIDTracestateEnabled OPENCODE_USER_ID_TRACESTATE_ENABLED true
userIDTracestateKey OPENCODE_USER_ID_TRACESTATE_KEY opencode_user_id

The default key uses underscores to stay within the W3C tracestate key syntax (lowercase letters, digits, _, -, *, / — no dots).

Skipped cases

Nothing is injected when the user ID is still unresolved (unknown), when the value contains characters invalid in a tracestate value (,, =, non-printable ASCII), or when the feature is disabled.

Notes

  • UNKNOWN_USER_ID is now exported from src/user-id.ts so the handler shares the constant instead of duplicating the literal.
  • bun run typecheck passes; bun test is 229/229 green (8 new cases across tests/chat-headers.test.ts and tests/config.test.ts).
  • oxfmt/oxlint are not installed in this checkout, so format:check and lint were not run.

🤖 Generated with Claude Code

Providers that receive W3C trace context now also receive the resolved
`user.id` as an extra tracestate member, merged into the tracestate
produced by propagation.

The injection sits behind the existing OPENCODE_TRACE_PROPAGATION_PROVIDERS
gate, so a tracestate is never sent without its traceparent. Two new
settings control it: OPENCODE_USER_ID_TRACESTATE_ENABLED (default true)
and OPENCODE_USER_ID_TRACESTATE_KEY (default opencode_user_id).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@slipfre slipfre left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@slipfre
slipfre merged commit f6ecfad into custom-730 Aug 19, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants